package com.zzxx.wechat.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.zzxx.wechat.adpater.ArcteryxTaskAdapter;
import com.zzxx.wechat.common.enums.ArcteryxSpuStatusEnum;
import com.zzxx.wechat.common.vo.ArcteryxCommodityVo;
import com.zzxx.wechat.common.vo.ArcteryxLinkVo;
import com.zzxx.wechat.dao.ArcteryxProductDao;
import com.zzxx.wechat.dao.ArcteryxSwitchDao;
import com.zzxx.wechat.entity.ArcteryxProduct;
import com.zzxx.wechat.entity.ArcteryxSwitch;
import com.zzxx.wechat.service.ArcteryxLinkService;
import com.zzxx.wechat.service.ArcteryxTaskService;
import com.zzxx.wechat.socket.SpringWebSocketHandler;
import com.zzxx.wechat.util.ArcteryxSwitchConstants;

import com.zzxx.wechat.util.TraceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ArcteryxTaskServiceImpl implements ArcteryxTaskService {

    @Resource
    private ArcteryxProductDao arcteryxProductDao;

    @Resource
    private ArcteryxLinkService arcteryxLinkService;
    @Resource
    private ArcteryxSwitchDao arcteryxSwitchDao;
    @Resource
    private SpringWebSocketHandler webSocketHandler;
    @Resource
    private ThreadPoolExecutor arcteryxJobExecutor;
    /**
     * 用于控制arcteryxJob方法执行的锁
     */
    private final ReentrantLock arcteryxJobLock = new ReentrantLock();

    public List<ArcteryxLinkVo> queryLinkByProductNos(List<String> productNoList) {
        // 获取开关配置
        ArcteryxSwitch arcteryxSwitch = arcteryxSwitchDao.queryByConfigName(ArcteryxSwitchConstants.CONFIG_SWITCH_NAME);
        boolean isEnable = arcteryxSwitch != null && arcteryxSwitch.getConfigSwitch() == 1;

        // 确定需要查询的商品编号
        List<String> needQueryProductNoList = isEnable
                ? getNeedQueryProductNos(productNoList)
                : new ArrayList<>(productNoList);

        // 并行查询商品链接
        if (CollectionUtil.isNotEmpty(needQueryProductNoList)) {
            //List<ArcteryxLinkVo> arcteryxLinkVoRes = arcteryxLinkService.parallelQueryProductLinks(needQueryProductNoList);
            List<ArcteryxLinkVo> arcteryxLinkVoRes = new ArrayList<>();
            // 根据开关状态返回结果
            if (!isEnable || needQueryProductNoList.size() == productNoList.size()) {
                return sortLinkVos(arcteryxLinkVoRes);
            }
        }

        return arcteryxLinkService.processExistingLinks(productNoList);
    }

    /**
     * 获取需要查询的商品编号
     */
    private List<String> getNeedQueryProductNos(List<String> productNoList) {
        List<ArcteryxProduct> arcteryxProducts = arcteryxProductDao.queryByNos(productNoList);
        List<String> existProductNoList = arcteryxProducts.stream()
                .map(ArcteryxProduct::getProductNo)
                .collect(Collectors.toList());

        return productNoList.stream()
                .filter(productNo -> !existProductNoList.contains(productNo))
                .collect(Collectors.toList());
    }

    /**
     * 对ArcteryxLinkVo列表进行排序
     */
    private List<ArcteryxLinkVo> sortLinkVos(List<ArcteryxLinkVo> linkVos) {
        return linkVos.stream()
                .sorted(Comparator.comparing(ArcteryxLinkVo::getSpuId))
                .collect(Collectors.toList());
    }


    public void asyncArcteryxJob() {
        arcteryxJobExecutor.execute(this::arcteryxJob);
    }

    public void arcteryxJob() {
        try {

            if (!arcteryxJobLock.tryLock(30, TimeUnit.SECONDS)) {
                log.info("循环任务获取锁失败");
                return;
            }
            TraceUtil.appendTraceId();
            for (; ; ) {

                // 获取开关配置
                ArcteryxSwitch arcteryxSwitch = arcteryxSwitchDao.queryByConfigName(ArcteryxSwitchConstants.CONFIG_SWITCH_NAME);

                if (arcteryxSwitch == null || arcteryxSwitch.getConfigSwitch() == 0) {
                    log.info("Arcteryx开关未开启");
                    return;
                }
                if (webSocketHandler.connectionNum() == 0) {
                    log.info("当前无用户连接");
                    return;
                }

                List<ArcteryxProduct> arcteryxProductList = arcteryxProductDao.queryByStatus(ArcteryxSpuStatusEnum.ENABLE);

                if (CollectionUtil.isEmpty(arcteryxProductList)) {
                    log.info("没有需要处理的Arcteryx产品");
                    return;
                }

                List<String> productNos = arcteryxProductList.stream().map(ArcteryxProduct::getProductNo).collect(Collectors.toList());

                List<ArcteryxCommodityVo> arcteryxCommodityVos = arcteryxLinkService.parallelQueryProductLinks(productNos);

                ArcteryxTaskAdapter.filterCommodityColor(arcteryxProductList, arcteryxCommodityVos);

/*                InputStream inputStream = getClass().getClassLoader().getResourceAsStream("json/arcteryx-product.json");
                String content = new String(FileCopyUtils.copyToByteArray(inputStream), StandardCharsets.UTF_8);
                List<ArcteryxCommodityVo> arcteryxCommodityVos = JSON.parseArray(content, ArcteryxCommodityVo.class);
                Thread.sleep(3000);*/

                webSocketHandler.sendMessageEvery(new TextMessage(JSON.toJSONString(arcteryxCommodityVos)));

            }
        } catch (Exception e) {
            log.error("执行Arcteryx定时任务时发生错误", e);
        } finally {
            if (arcteryxJobLock.isHeldByCurrentThread()) {
                arcteryxJobLock.unlock();
            }
        }

    }

}
